# -*- coding: utf-8 -*-
"""
购物管理系统 - 数据分析模块
"""

# 标准库导入
from fastApi.database.base import MysqlLite
import sys
import warnings
import json
from datetime import datetime, timedelta

# 忽略特定字体警告
warnings.filterwarnings("ignore", category=UserWarning, message="Glyph 165")

# 第三方库导入
import numpy as np
import pandas as pd
import requests
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

# 设置 matplotlib 字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'Arial Unicode MS', 'SimHei', 'Noto Sans CJK JP']
plt.rcParams['axes.unicode_minus'] = False

# PyQt5 导入
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QTabWidget,
    QLabel, QPushButton, QComboBox, QSpinBox, QFrame,
    QGridLayout, QScrollArea, QWidget as QWidgetBase, QApplication
)
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
from PyQt5.QtGui import QFont, QPalette, QColor, QIcon


class AnalyticsWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowIcon(QIcon('./images/购物.png'))
        self.init_ui()
        self.load_data()

        # 设置定时器，每5分钟刷新一次数据
        self.timer = QTimer()
        self.timer.timeout.connect(self.load_data)
        self.timer.start(300000)  # 5分钟 = 300000毫秒

    def init_ui(self):
        """初始化用户界面"""
        layout = QVBoxLayout()
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(20)

        # 标题
        title = QLabel("数据分析中心")
        title.setFont(QFont("Microsoft YaHei", 20, QFont.Bold))
        title.setAlignment(Qt.AlignCenter)
        title.setStyleSheet("""
            QLabel {
                color: white;
                padding: 10px;
                background-color: #ff5f00;
                border-radius: 8px;
            }
        """)
        layout.addWidget(title)

        # 创建标签页
        self.tab_widget = QTabWidget()
        self.tab_widget.setStyleSheet("""
            QTabWidget::pane {
                border: 2px solid #ddd;
                border-radius: 10px;
                background-color: #f8f9fa;
            }
            QTabBar::tab {
                background-color: #ffffff;
                color: #ff5f00;
                padding: 10px 20px;
                margin: 2px;
                border: 1px solid #ddd;
                border-top-left-radius: 8px;
                border-top-right-radius: 8px;
                font-weight: bold;
            }
            QTabBar::tab:selected {
                background-color: #ff5f00;
                color: white;
            }
            QTabBar::tab:hover {
                background-color: #ffe5cc;
            }
        """)

        # 添加各分析标签页
        self.tabs = {
            "销售概览": OverviewTab(),
            "分类分析": CategoryAnalysisTab(),
            "客户分析": CustomerAnalysisTab()
        }

        for name, tab in self.tabs.items():
            self.tab_widget.addTab(tab, name)

        layout.addWidget(self.tab_widget)

        # 刷新按钮
        refresh_layout = QHBoxLayout()
        refresh_btn = QPushButton("刷新数据")
        refresh_btn.setCursor(Qt.PointingHandCursor)
        refresh_btn.clicked.connect(lambda: [print("刷新按钮点击"), self.load_data()])
        refresh_btn.setStyleSheet("""
            QPushButton {
                background-color: #ff5f00;
                color: white;
                padding: 10px 20px;
                border-radius: 5px;
                font-size: 14px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #e65b00;
            }
            QPushButton:pressed {
                background-color: #cc5200;
            }
        """)
        refresh_layout.addStretch()
        refresh_layout.addWidget(refresh_btn)
        layout.addLayout(refresh_layout)

        self.setLayout(layout)

    def load_data(self):
        """加载所有数据"""
        try:
            for tab in self.tabs.values():
                tab.load_data()
        except Exception as e:
            print(f"加载数据时发生错误: {e}")


class OverviewTab(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.db = MysqlLite()  # 初始化数据库连接
        self.load_data()  # 加载数据

    def init_ui(self):
        """初始化概览界面"""
        layout = QVBoxLayout()

        # 创建网格布局用于显示统计卡片
        grid_layout = QGridLayout()
        grid_layout.setSpacing(15)

        # 统计卡片
        self.cards = {
            "总订单数": self.create_stat_card("总订单数", "0", "#ff5f00"),
            "总销售额": self.create_stat_card("总销售额", "¥0", "#e74c3c"),
            "总商品数": self.create_stat_card("总商品数", "0", "#ff5f00"),
            "平均订单": self.create_stat_card("平均订单", "¥0", "#ff5f00")
        }

        # 添加到网格布局
        for i, (name, card) in enumerate(self.cards.items()):
            row = i // 2
            col = i % 2
            grid_layout.addWidget(card, row, col)

        layout.addLayout(grid_layout)
        self.setLayout(layout)

    def create_stat_card(self, title, value, color):
        """创建统计卡片"""
        card = QFrame()
        card.setFrameStyle(QFrame.Box)
        card.setStyleSheet(f"""
            QFrame {{
                background-color: white;
                border: 1px solid #ddd;
                border-radius: 10px;
                padding: 15px;
                margin: 10px;
            }}
            QFrame:hover {{
                border: 2px solid #ff5f00;
            }}
        """)

        layout = QVBoxLayout()

        # 标题
        title_label = QLabel(title)
        title_label.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet(f"color: {color};")

        # 值
        value_label = QLabel(value)
        value_label.setFont(QFont("Microsoft YaHei", 18, QFont.Bold))
        value_label.setAlignment(Qt.AlignCenter)
        value_label.setStyleSheet(f"color: {color};")

        layout.addWidget(title_label)
        layout.addWidget(value_label)
        card.setLayout(layout)
        return card

    def load_data(self):
        """加载销售概览数据"""
        try:
            conn = self.db
            # 获取总订单数
            conn.operation_sql("SELECT COUNT(*) FROM orders")
            conn.query.next()
            total_orders = conn.query.value(0)

            # 获取总销售额
            conn.operation_sql("SELECT SUM(price * quantity) FROM orders")
            conn.query.next()
            total_sales = conn.query.value(0) or 0

            # 获取总商品数量
            conn.operation_sql("SELECT SUM(quantity) FROM orders")
            conn.query.next()
            total_quantity = conn.query.value(0) or 0

            # 获取平均订单金额
            avg_order_value = total_sales / total_orders if total_orders > 0 else 0

            # 更新卡片数据
            self.cards["总订单数"].layout().itemAt(1).widget().setText(str(total_orders))
            self.cards["总销售额"].layout().itemAt(1).widget().setText(f"¥{round(total_sales, 2)}")
            self.cards["总商品数"].layout().itemAt(1).widget().setText(str(total_quantity))
            self.cards["平均订单"].layout().itemAt(1).widget().setText(f"¥{round(avg_order_value, 2)}")
        except Exception as e:
            print(f"加载概览数据失败: {e}")


class CategoryAnalysisTab(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        """初始化分类分析界面"""
        layout = QVBoxLayout()

        # 图表
        self.figure = Figure(figsize=(12, 8))
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setStyleSheet("border: 2px solid #ddd; border-radius: 10px; background-color: white;")
        layout.addWidget(self.canvas)

        self.setLayout(layout)

    def load_data(self):
        """加载分类分析数据"""
        try:
            response = requests.get("http://127.0.0.1:8000/api/analytics/category-analysis")
            if response.status_code == 200:
                data = response.json()
                print(f"分类分析数据: {data}")  # 调试：打印 API 数据
                if data:
                    self.plot_category_analysis(data)
            else:
                print(f"获取分类分析数据失败: {response.status_code}")
        except Exception as e:
            print(f"加载分类分析数据失败: {e}")

    def plot_category_analysis(self, data):
        """绘制分类分析图表"""
        try:
            self.figure.clear()
            ax = self.figure.add_subplot(111)

            categories = [d["category_name"] for d in data]
            total_sales = [d["total_sales"] for d in data]

            bars = ax.bar(categories, total_sales, color="#ff5f00")
            ax.set_xlabel("分类", fontsize=10)
            ax.set_ylabel("总销售额 (¥)", fontsize=10)
            ax.set_title("分类销售分析", fontweight="bold", fontsize=12)
            ax.grid(True, alpha=0.3)

            for bar in bars:
                height = bar.get_height()
                ax.text(bar.get_x() + bar.get_width() / 2, height,
                        f'¥{height:.0f}', ha="center", va="bottom", fontsize=8)

            plt.xticks(rotation=45)
            plt.tight_layout()
            self.canvas.draw()
        except Exception as e:
            print(f"绘制分类分析图表失败: {e}")
            self.figure.clear()
            ax = self.figure.add_subplot(111)
            ax.text(0.5, 0.5, f'绘制图表失败: {str(e)}', horizontalalignment='center',
                    verticalalignment='center', transform=ax.transAxes, fontsize=12, color='red')
            self.canvas.draw()


class CustomerAnalysisTab(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        """初始化客户分析界面"""
        layout = QVBoxLayout()

        # 图表
        self.figure = Figure(figsize=(12, 6))  # 调整整体图表大小
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setStyleSheet("border: 2px solid #ddd; border-radius: 10px; background-color: white;")
        layout.addWidget(self.canvas)

        self.setLayout(layout)

    def load_data(self):
        """加载客户分析数据"""
        try:
            response = requests.get("http://127.0.0.1:8000/api/analytics/customer-analysis")
            if response.status_code == 200:
                data = response.json()
                print(f"客户分析数据: {data}")  # 调试：打印 API 数据
                if data:
                    self.plot_customer_analysis(data)
            else:
                print(f"获取客户分析数据失败: {response.status_code}")
        except Exception as e:
            print(f"加载客户分析数据失败: {e}")

    def plot_customer_analysis(self, data):
        """绘制客户分析图表"""
        try:
            self.figure.clear()
            ax1 = self.figure.add_subplot(121)  # 左侧子图
            ax3 = self.figure.add_subplot(122)  # 右侧子图

            df = pd.DataFrame(data)
            # 检查必需字段
            required_columns = ['customer_name', 'total_spent', 'order_count']
            missing_columns = [col for col in required_columns if col not in df.columns]
            if missing_columns:
                ax1.text(0.5, 0.5, f'数据格式错误：缺少字段 {", ".join(missing_columns)}',
                         horizontalalignment='center', verticalalignment='center',
                         transform=ax1.transAxes, fontsize=12, color='red')
                self.canvas.draw()
                return

            top_customers = df.head(10)
            customer_names = [name[:8] + '...' if len(name) > 8 else name for name in top_customers['customer_name']]

            bars = ax1.barh(range(len(customer_names)), top_customers['total_spent'], color='#ff5f00')
            ax1.set_yticks(range(len(customer_names)))
            ax1.set_yticklabels(customer_names)
            ax1.set_title('客户消费排行 (前10名)', fontweight='bold', fontsize=10)
            ax1.set_xlabel('消费金额 (¥)', fontsize=10)
            ax1.set_xlim(0, max(top_customers['total_spent']) * 1.2)  # 增加 x 轴空间

            for i, bar in enumerate(bars):
                width = bar.get_width()
                ax1.text(width + max(top_customers['total_spent']) * 0.01, bar.get_y() + bar.get_height() / 2,
                         f'¥{width:.0f}', ha='left', va='center', fontsize=8)

            ax3.scatter(df['order_count'], df['total_spent'], alpha=0.6, s=60, color='#ff5f00')
            ax3.set_xlabel('订单数量', fontsize=10)
            ax3.set_ylabel('消费金额 (¥)', fontsize=10)
            ax3.set_title('订单数量与消费金额关系', fontweight='bold', fontsize=10)
            ax3.grid(True, alpha=0.3)
            ax3.set_xlim(0, max(df['order_count']) * 1.2)  # 增加 x 轴空间
            ax3.set_ylim(0, max(df['total_spent']) * 1.2)  # 增加 y 轴空间

            # 调整子图布局
            plt.tight_layout(pad=3.0, w_pad=4.0, h_pad=2.0)  # 增加间距
            self.canvas.draw()
        except Exception as e:
            print(f"绘制客户分析图表失败: {e}")
            self.figure.clear()
            ax = self.figure.add_subplot(111)
            ax.text(0.5, 0.5, f'绘制图表失败: {str(e)}', horizontalalignment='center',
                    verticalalignment='center', transform=ax.transAxes, fontsize=12, color='red')
            self.canvas.draw()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    font = QFont("Microsoft YaHei", 10)
    app.setFont(font)
    window = AnalyticsWidget()
    window.setWindowTitle("购物管理系统 - 数据分析")
    window.resize(1200, 800)
    window.show()
    sys.exit(app.exec_())